package com.zmc.dynamic.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @desc:字符串工具类
 * @date: 2019-07-02
 */
@Slf4j
public class StringUtil {

    public final static String UTF8 = "UTF-8";

    /**
     * 版本号比较
     *
     * @param v1
     * @param v2
     * @return 0代表相等，1代表左边大，-1代表右边大
     * StringUtil.compareVersion("1.0.358_20180820090554","1.0.358_20180820090553")=1
     */
    public static int compareVersion(String v1, String v2) {
        if (v1.equals(v2)) {
            return 0;
        }
        String[] version1Array = v1.split("[._]");
        String[] version2Array = v2.split("[._]");
        int index = 0;
        int minLen = Math.min(version1Array.length, version2Array.length);
        long diff = 0;

        while (index < minLen
                && (diff = Long.parseLong(version1Array[index])
                - Long.parseLong(version2Array[index])) == 0) {
            index++;
        }
        if (diff == 0) {
            for (int i = index; i < version1Array.length; i++) {
                if (Long.parseLong(version1Array[i]) > 0) {
                    return 1;
                }
            }

            for (int i = index; i < version2Array.length; i++) {
                if (Long.parseLong(version2Array[i]) > 0) {
                    return -1;
                }
            }
            return 0;
        } else {
            return diff > 0 ? 1 : -1;
        }
    }


    /**
     * 百分比
     * @param num1
     * @param num2
     * @return
     */
    public static String percentage(int num1,int num2){
        return percentageInt(num1 , num2) + "%";
    }

    public static String percentage(long num1,long num2){
        return percentageInt(num1 , num2) + "%";
    }

    /**
     * 百分比
     * @param num1
     * @param num2
     * @return
     */
    public static String percentageInt(long num1,long num2){
        return percentageDouble(num1,num2)+"";

    }

    public static double percentageDouble(long num1, long num2) {
        double a = 0;
        if (num1 == 0 || num2 == 0) {
            return a;
        } else {
            NumberFormat numberFormat = NumberFormat.getInstance();
            numberFormat.setMaximumFractionDigits(2); //设置，小数点最多两位数
            numberFormat.setGroupingUsed(false); //关闭分组，显示将不再以千位符分隔
            String result = numberFormat.format((float) num1 / (float) num2 * 100);
            if(null != result && !result.equals("")){
                return Double.parseDouble(result);
            }
            return a;
        }
    }
    /**
     * 密码强度验证
     */
    public static boolean checkPass(String pass){
        if(isContainChinese(pass)){
            return false;
        }
        if((isContainByNum(pass) && isContainByAZ(pass) && isContainByaz(pass))
                || (isContainByNum(pass) && isContainByAZ(pass))
                || (isContainByNum(pass) && isContainBySymbol(pass))
                || (isContainByaz(pass) && isContainBySymbol(pass))
                || (isContainByAZ(pass) && isContainBySymbol(pass))
                || (isContainByNum(pass) && isContainByaz(pass))){
            if(pass.length() < 10){
                return false;
            }
            return true;
        }
        return false;
    }
    /**
     *  检查字符串是否包含数字
     */
    public static boolean isContainBySymbol(String str){
        if(isEmpty(str)){
            return false;
        }
        Pattern pattern = Pattern.compile(".*[!@#$%^&*_=+].*");
        return pattern.matcher(str).matches();
    }
    /**
     *  检查字符串是否包含数字
     */
    public static boolean isContainByNum(String str){
        if(isEmpty(str)){
            return false;
        }
        Pattern pattern = Pattern.compile(".*[0-9].*");
        return pattern.matcher(str).matches();
    }
    /**
     *  检查字符串是否包含大写字母
     */
    public static boolean isContainByAZ(String str){
        if(isEmpty(str)){
            return false;
        }
        Pattern pattern = Pattern.compile(".*[A-Z].*");
        return pattern.matcher(str).matches();
    }
    /**
     *  检查字符串是否包含小写字母
     */
    public static boolean isContainByaz(String str){
        if(isEmpty(str)){
            return false;
        }
        Pattern pattern = Pattern.compile(".*[a-z].*");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断是否存在中文
     * @param str
     * @return
     */
    public static boolean isContainChinese(String str) {
        if(isEmpty(str)){
            return false;
        }
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * 是否是数字
     * @param str
     * @return
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }


    /**
     * 判断null
     *
     * @param obj
     */
    public static void checkIsNull(Object obj, String msg) {
        if (obj == null) {
            throw new RuntimeException(msg);
        }
    }

    public static String encodeUrl(String input) {
        try {
            return URLEncoder.encode(input, UTF8);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 生成随机数当作getItemID
     * n ： 需要的长度
     * @return
     */
    public static String getItemID( int n ) {
        String val = "";
        Random random = new Random();
        for ( int i = 0; i < n; i++ )
        {
            String str = random.nextInt( 2 ) % 2 == 0 ? "num" : "char";
            if ( "char".equalsIgnoreCase( str ) )
            { // 产生字母
                int nextInt = random.nextInt( 2 ) % 2 == 0 ? 65 : 97;

                val += (char) ( nextInt + random.nextInt( 26 ) );
            }
            else if ( "num".equalsIgnoreCase( str ) )
            { // 产生数字
                val += String.valueOf( random.nextInt( 10 ) );
            }
        }
        return val;
    }

    /**
     * 判断是否是纯中文
     * @param string
     * @return
     */
    public static boolean isChinese(String string) {
        if(StringUtil.isEmpty(string)){
            return false;
        }
        // TODO Auto-generated method stub
        if (string.replaceAll("[\u4e00-\u9fa5]", "").length() == 0) {
            //如果不包含特殊字符
            return true;
        }
        return false;
    }
    /**
     * 过滤掉非汉字内容
     * @param buff
     * @return
     */
    public static String clearNotChinese(String buff){
        if(isEmpty(buff)){
            return null;
        }
        //去掉所有中英文符号
        String tmpString =buff.replaceAll("(?i)[^a-zA-Z0-9\u4E00-\u9FA5]", "");

        char[] carr = tmpString.toCharArray();

        for(int i = 0; i<tmpString.length();i++){

            if(carr[i] < 0xFF){
                //过滤掉非汉字内容
                carr[i] = ' ' ;
            }
        }
        String trim = String.copyValueOf(carr).trim();
        if(trim.contains(" ")){
            return trim.split(" ")[0];
        }
        return trim;

    }

    /**
     * 正则进行过滤  特殊字符表情
     * @param str
     * @return
     */
    public static String replaceEmoji(String str) {
        String patternString = "[\uD83E\uDDF8]|[\uD83C\uDC04-\uD83C\uDE1A]|[\uD83D\uDC66-\uD83D\uDC69]|[\uD83D\uDC66\uD83C\uDFFB-\uD83D\uDC69\uD83C\uDFFF]|[\uD83D\uDE45\uD83C\uDFFB-\uD83D\uDE4F\uD83C\uDFFF]|[\uD83C\uDC00-\uD83D\uDFFF]|[\uD83E\uDD10-\uD83E\uDDC0]|[\uD83D\uDE00-\uD83D\uDE4F]|[\uD83D\uDE80-\uD83D\uDEF6]";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        return filterName(matcher.replaceAll(""));
    }


    /**
     * 过滤昵称特殊表情
     */
    public static String filterName(String name) {
        if(name==null) return null;
        if("".equals(name.trim())) return "";

        Pattern patter = Pattern.compile("[a-zA-Z0-9\u4e00-\u9fa5]");
        Matcher match = patter.matcher(name);

        StringBuffer buffer = new StringBuffer();
        boolean flag=false;
        while (match.find()) {
            buffer.append(match.group());
        }
        if(!name.equals(buffer.toString())){
            flag=true;
        }
        if(flag)
            return buffer.toString();
        else
            return buffer.toString();
    }

    /**
     * 判断字符串是否为空
     * @param str
     * null、“ ”、“null”都返回true
     * @return
     */
    public static boolean isNullString(String str) {
        return (null == str || StringUtils.isEmpty(str.trim()) || "null".equals(str.trim().toLowerCase())) ? true : false;
    }
    public static boolean isNullObject(Object obj) {
        if(obj==null){
            return true;
        }else if(obj instanceof String) {
            return isNullString((String)obj);
        } else if(obj instanceof Double) {
            return false;
        }
        return false;
    }

    /**
     * 功能：校验手机号是否符合标准
     * @param mobilePhone
     * @return
     */
    public static boolean isMobilePhone(String mobilePhone){
        if(isEmpty(mobilePhone)){
            return false;
        }
        return mobilePhone.matches("^1(3[0-9]|4[5,7]|5[0-9]|6[2,5,6,7]|7[0-9]|8[0-9]|9[1,8,9])\\d{8}$");
    }
    /**
     * 格式化字符串
     * 如果为空，返回“”
     * @param str
     * @return
     */
    public static String formatString(String str) {
        if(isNullString(str)) {
            return "";
        } else {
            return str;
        }
    }

    /**
     * 截取字符串，字母、汉字都可以，汉字不会截取半
     * @param str 字符串
     * @param n 截取的长度，字母数，如果为汉字，一个汉字等于两个字母数
     * @return
     */
	public static String subStringByByte(String str, int n) {
		int num = 0;
		try {
			byte[] buf = str.getBytes("GBK");
			if (n >= buf.length) {
				return str;
			}
			boolean bChineseFirstHalf = false;
			for (int i = 0; i < n; i++) {
				if (buf[i] < 0 && !bChineseFirstHalf) {
					bChineseFirstHalf = true;
				} else {
					num++;
					bChineseFirstHalf = false;
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str.substring(0, num);
	}

    /**
     * Created by zhoujun on 2014/5/30
     * 验证输入的是否是数字
     * @param num 字符串数字
     * @return
     *
     */
    public static boolean inputIsNum(final String num) {
        boolean flag = true;
        try {
            Long.valueOf(num);
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    public static boolean inputIsDouble(String num){
        boolean flag = true;
        try {
            Double.valueOf(num);
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 替换中间字符串
     * @param str
     * @param n
     * @return
     */
    public static String replaceSubString(String str,int n){
    	String repaceStr="";
		try {
			//前n位
			String headStr = str.substring(0, n);
			//后n位
			String lastStr = str.substring(str.length() - n, str.length());
			/**
			 * 中间的字符串替换*
			 */
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < str.length()-2*n; i++) {
				sb = sb.append("*");
			}
			repaceStr=	headStr+sb.toString()+lastStr;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return repaceStr;
    }

    /**
     * 替换中间字符串
     * @param str
     * @param replaceChar 替换符
     * @param startPosition 开始位置(下标从1开始算)
     * @param endPosition  结束位置(下标从1开始算)
     * @return
     */
    public static String replaceString(String str,char replaceChar,int startPosition,int endPosition){
        if(isNullString(str)){
            return str;
        }
        char val[] =str.toCharArray();
        char buf[] = new char[str.length()];
        for (int j = 0; j <str.length(); j++) {
            if(j<(startPosition-1)||j>(endPosition-1)) {
                buf[j]=val[j];
            } else {
                buf[j]=replaceChar;
            }

        }
        return new String(buf);
    }
    /**
     * 截取后N位字符串
     * @param str
     * @return
     */
    public static String subString(String str,int length){
        return str.substring(str.length()-length,str.length());
    }
    /**
     * 替换身份证号中间字符串
     * @param str
     * @return
     */
    public static String replaceIndentityNoString(String str){
        if(isNullString(str)){
            return str;
        }
        return replaceString(str, '*', 9, 14);
    }

    public static String handleBankCardString(String str){
        if(isNullString(str)){
            return str;
        }
        return subString(str,4);
    }
    /**
     * 替换身份证号中间字符串
     * @param str
     * @return
     */
    public static String replacePhoneString(String str){
        if(isNullString(str)){
            return str;
        }
        return replaceString(str, '*', 4, 7);
    }
     /**
     * Description: 反转字符数组
     * @param motoArr 原始数组
     * @return String[]
     */
    public static String[] reverseStringArray(String[] motoArr)
    {
        int length = motoArr.length;

        String[] atarashiArr = new String[length];

        for (int i = 0, j = length - 1; i < length; i++, j--)
        {
            atarashiArr[i] = motoArr[j];
        }

        return atarashiArr;
    }


    /**
     * 格式化数字 #,###.##
     * @param balance
     * @param point 保留小数位数
     * @return
     */
    public static String formatDecimal(Double balance,int point) {
        if(isNullObject(balance)){
            return "";
        }
        StringBuffer sb=new StringBuffer("#,###.");
        for(int i=0;i<point;i++){
            sb.append("#");
        }
        DecimalFormat df =new DecimalFormat(sb.toString());
        return df.format(balance);
    }
    /**
     * 获取前idxNum个标签
     * @param sign 标签字符串","分割
     * @param idxNum 第几个
     * @return
     */
    public static String getFirstFewSign(String sign,int idxNum) {
        if (isNullString(sign)) {
            return sign;
        }
        Matcher signMatcher = Pattern.compile(",").matcher(sign);
        int signIdx = 0;
        while (signMatcher.find()) {
            signIdx++;
            if (signIdx == idxNum) {
                break;
            }
        }
        if (signIdx < idxNum) {
            return sign;
        }
        signIdx = signMatcher.start();
        return sign.substring(0, signIdx);
    }

    /**
     * 金额转换成字符串
     * @param amount 整形金额(单位分)
     * @param isMicrometer 是否千分位显示 默认true
     * @return 如 10004613格式化为 10,0046.13
     */
    public static String formatAmount(Integer amount,boolean isMicrometer) {
        if(amount==null){
            return "0.00";
        }
        BigDecimal bigAmount=new BigDecimal(amount).divide(new BigDecimal("100"));
        if(isMicrometer){
            DecimalFormat df=new DecimalFormat(",###0.00");
            return df.format(bigAmount);
        }else{
            DecimalFormat df=new DecimalFormat("###0.00");
            return df.format(bigAmount);
        }
    }
    /**
     * 金额转换成字符串
     * @param amount 整形金额(单位分)
     * @param isMicrometer 是否千分位显示 默认true
     * @return 如 10004613格式化为 10,0046.13
     */
    public static String formatAmount(Long amount,boolean isMicrometer) {
        if(amount==null){
            return "0.00";
        }
        BigDecimal bigAmount=new BigDecimal(amount).divide(new BigDecimal("100"));
        if(isMicrometer){
            DecimalFormat df=new DecimalFormat(",###0.00");
            return df.format(bigAmount);
        }else{
            DecimalFormat df=new DecimalFormat("###0.00");
            return df.format(bigAmount);
        }
    }
    /**
     * 金额转换成字符串(千分位显示)
     * @param amount 整形金额(单位分)
     * @return 如 10004613格式化为 10,0046.13
     */
    public static String formatAmount(Integer amount) {
       return formatAmount(amount,false);
    }
    /**
     * 金额转换成字符串(千分位显示)
     * @param amount 整形金额(单位分)
     * @return 如 10004613格式化为 10,0046.13
     */
    public static String formatAmount(Long amount) {
        return formatAmount(amount,false);
    }
    /**
     * 获取卡号后后四位
     */
    public static String getCardNoFourAfterFour(String cardNo) {
        if(cardNo==null||cardNo.length()<4){
            return cardNo;
        }
        return cardNo.substring(cardNo.length()-4,cardNo.length());
    }

    /**
     * 打码用户名
     * @param clientName
     * @return
     */
    public static String replaceClientNameString(String clientName) {
        if(clientName==null||clientName.length()<1){
            return clientName;
        }
        return replaceString(clientName, '*', 1, clientName.length()-1);
    }

    public static String getDefault(String str) {
        if(StringUtils.isEmpty(str)) {
            return "";
        }
        return str;
    }
    /**
     * 利率转换成百分比 乘以100
     * @param rate 利率
     * @return 如 0.2555格式化为25.55
     */
    public static String formatRate(String rate) {
        if(rate==null){
            return "0.00";
        }
        BigDecimal bigAmount=new BigDecimal(rate).multiply(new BigDecimal("100"));
        DecimalFormat df=new DecimalFormat("###0.00");
        return df.format(bigAmount);
    }
    public static boolean isEmpty(String str) {
        return (str == null || str.trim().length() == 0 || "null".equals(str) || "".equals(str));
    }
    public static boolean isEmpty(JSONObject dataJson) {
        return dataJson == null || dataJson.isEmpty();
    }

    public static boolean isEmpty(JSONArray  dataJson) {
        return dataJson == null || dataJson.isEmpty();
    }

    public static boolean isNotEmpty(JSONObject dataJson) {
        return (dataJson != null && !dataJson.isEmpty());
    }

    public static boolean isNotEmpty(JSONArray  dataJson) {
        return (dataJson != null && !dataJson.isEmpty());
    }

    public static boolean isNotEmpty(String str) {
        return (str != null && str.trim().length() != 0 && !"null".equals(str) && !"".equals(str));
    }

    public static boolean isEmpty(String[] strs) {
        return (strs == null || strs.length == 0);
    }

    public static boolean isNotEmpty(String[] strs) {
        return (strs != null && strs.length != 0);
    }

    public static <T> boolean isEmpty(List<T> list) {
        return (list == null || list.isEmpty());
    }

    public static <T> boolean isNotEmpty(List<T> list) {
        return (list != null && !list.isEmpty());
    }

    public static <K, V> boolean isEmpty(Map<K, V> map) {
        return (map == null || map.isEmpty());
    }

    public static <K, V> boolean isNotEmpty(Map<K, V> map) {
        return (map != null && !map.isEmpty());
    }
    /**
     * 转换为下划线
     *
     * @param camelCaseName
     * @return
     */
    public static String underscoreName(String camelCaseName) {
        StringBuilder result = new StringBuilder();
        if (camelCaseName != null && camelCaseName.length() > 0) {
            result.append(camelCaseName.substring(0, 1).toLowerCase());
            for (int i = 1; i < camelCaseName.length(); i++) {
                char ch = camelCaseName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    result.append("_");
                    result.append(Character.toLowerCase(ch));
                } else {
                    result.append(ch);
                }
            }
        }
        return result.toString();
    }

    /**
     * list转换为字符串
     */

    public static String joinToString(List<String> list){
        return Joiner.on(",").join(list);
    }


    /**
     * map转换为字符串
     */

    public static String convertMapToString(Map<String, Integer> salary) {
        return Joiner.on(" , ").withKeyValueSeparator(" = ").join(salary);
    }

    /**
     * list转String，跳过null
     */

    public static  String convertListToStringAndSkipNull(List<String> list) {
        return Joiner.on(",").skipNulls().join(list);
    }

    /**
     *  list转String，将null变成其他值
     *  List<String> names = Lists.newArrayList("John", null, "Jane", "Adam", "Tom");
     * @param list
     * @param useForNull null  需要转换的值
     * @return
     */

    public static String useForNull(List<String> list,String useForNull) {
        return Joiner.on(",").useForNull(useForNull).join(list);
    }

    /**
     * String to List
     */

    public static List<String> createListFromString(String input) {
        return Splitter.on(",").trimResults().splitToList(input);
    }

    /**
     * String to List
     */

    public static List<String> createListFromString(String input,String pattern) {
        return Splitter.on(pattern).trimResults().splitToList(input);
    }

    /**
     * String to Map
     * @param input John=first,Adam=second
     */

    public static Map<String, String> createMapFromString(String input) {
        return Splitter.on(",").withKeyValueSeparator("=").split(input);
    }

    /**
     * 多个字符进行分割
     * @param input
     * @param pattern [.|,]
     * @return
     */

    public static List<String> splitStringOnMultipleSeparator(String input,String pattern) {
        if(isEmpty(pattern)){
            pattern = "[.|,]";
        }
        return Splitter.onPattern(pattern).omitEmptyStrings().splitToList(input);
    }

    /**
     * 每隔多少字符进行分割
     */

    public static List<String> splitStringOnSpecificLength(String input, int sizi) {
        return Splitter.fixedLength(sizi).splitToList(input);
    }

    /**
     * 限制分割多少字后停止
     */

    public static List<String> limitSplitting(String input , int sizi) {
        return Splitter.on(",").limit(sizi).splitToList(input);
    }

}
